﻿using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using X = Adjunct.Framework.Nuspec.XNames.Package.Files;

namespace Adjunct.Framework.Nuspec
{
	/// <summary>
	/// 
	/// </summary>
	/// <remarks></remarks>
	public class NuspecIncludes : List<NuspecInclude>
	{
		/// <summary>
		/// Adds the specified source.
		/// </summary>
		/// <param name="source">The source.</param>
		/// <param name="target">The target.</param>
		/// <param name="exclude">The exclude.</param>
		/// <remarks></remarks>
		public void Add(string source, string target = null, string exclude = null)
		{
			Add(new NuspecInclude(source, target, exclude));
		}

		/// <summary>
		/// Clones this instance.
		/// </summary>
		/// <returns></returns>
		/// <remarks></remarks>
		public NuspecIncludes Clone()
		{
			NuspecIncludes clone = new NuspecIncludes();
			clone.AddRange(this.Select(include => include.Clone()));
			return clone;
		}

		/// <summary>
		/// Performs an explicit conversion from <see cref="Adjunct.Framework.Nuspec.NuspecIncludes"/> to 
		/// <see cref="System.Xml.Linq.XElement"/>.
		/// </summary>
		/// <param name="includes">The includes.</param>
		/// <returns>
		/// Returns null if the includes are null or empty for sparse xml.
		/// </returns>
		public static explicit operator XElement(NuspecIncludes includes)
		{
			if ((includes == null) || (includes.Count == 0))
			{
				return null;
			}
			return new XElement(X.ElementName, includes.OrderBy(i => i.Source).Select(i => (XElement)i));
		}

		/// <summary>
		/// Performs an explicit conversion from <see cref="System.Xml.Linq.XElement"/> to 
		/// <see cref="Adjunct.Framework.Nuspec.NuspecIncludes"/>.
		/// </summary>
		/// <param name="element">The element.</param>
		/// <returns>
		/// Always returns an instance so that the consumer doesn't have to see if one was created.
		/// </returns>
		public static explicit operator NuspecIncludes(XElement element)
		{
			NuspecIncludes includes = new NuspecIncludes();
			if (element != null)
			{
				element.EnsureElementNameIs(X.ElementName);
				includes.AddRange(element.Elements(X.File.ElementName).Select(child => (NuspecInclude)child));
			}
			return includes;
		}
	}
}